package com.ruoyi.report.forms.util;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.report.forms.domain.CngScadaRealtimeMonitoringHour;
import com.ruoyi.report.forms.domain.DispatchAccessDataDay;
import com.ruoyi.report.forms.domain.vo.ShiftsContentVO;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.util.StringUtil;
import org.apache.poi.xssf.streaming.SXSSFCell;
import org.apache.poi.xssf.streaming.SXSSFSheet;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class ExcelDataSelect extends DataSelect {

    public ExcelDataSelect(SXSSFSheet _sheet, JSONArray _bindata, String date, String month) {
        super(_sheet, _bindata, date, month);
    }

    public void WriteExcelData() {
        for (int i = 0; i < bindata.size(); i++) {
            JSONObject data = bindata.getJSONObject(i);
            switch (data.getString("type")) {
                case "station_day":
                    Write_Station_Day(data);
                    break;
                case "station_day_sum_flow":
                    Write_Station_Day_Sum_Flow(data);
                    break;
                case "station_month":
                    Write_Station_Month(data);
                    break;
                case "station_month_calc":
                    Write_Station_Month_Calc(data);
                    break;
                case "into_out":
                    Write_Into_Out(data);
                    break;
                case "shift_turnover":
                    Write_Shift_Turnover(data);
                    break;
                case "current_date":
                    Write_Current_Date(data);
                    break;
            }
        }
    }

    // 在表格中写入--场站设备小时数据
    private void Write_Station_Day(JSONObject data) {
        int ri_s = data.getInteger("r_start");
        int ri_e = data.getInteger("r_end");
        int ci_s = data.getInteger("c_start");

        List<CngScadaRealtimeMonitoringHour> cols = station_day.stream().filter((CngScadaRealtimeMonitoringHour row) -> row.getAttributeId().equals(data.getString("attributeId"))).collect(Collectors.toList());
        List<CngScadaRealtimeMonitoringHour> cols_custom = station_day_custom.stream().filter((CngScadaRealtimeMonitoringHour row) -> row.getAttributeId().equals(data.getString("attributeId"))).collect(Collectors.toList());

        String decimalPlace = data.getString("decimalPlace");
        int decimal = 2;
        if (NumberUtils.isCreatable(decimalPlace)) {
            decimal = Integer.parseInt(decimalPlace);
        }

        SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar calendar = Calendar.getInstance();

        int index = ri_s - 1;
        for (int i = 0; i < DayHourArr.length; i++) {
            String hour = DayHourArr[i];

            Date equalDate = null;
            try {
                equalDate = sdFormat.parse(date);
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }

            calendar.setTime(equalDate);
            if (i > 16) {
                calendar.add(Calendar.DATE, 1);
            }
            equalDate = calendar.getTime();
            String resultDate = sdFormat.format(equalDate) + " " + hour;

            List<CngScadaRealtimeMonitoringHour> cols_row = cols.stream().filter((CngScadaRealtimeMonitoringHour row) -> sdf.format(row.getUpdateTime()).equals(resultDate)).collect(Collectors.toList());
            List<CngScadaRealtimeMonitoringHour> cols_custom_row = cols_custom.stream().filter((CngScadaRealtimeMonitoringHour row) -> sdf.format(row.getUpdateTime()).equals(resultDate)).collect(Collectors.toList());

            String val = null;
            if (!cols_row.isEmpty()) {
                val = cols_row.get(0).getMonitoringValue();
            }
            if (!cols_custom_row.isEmpty()) {
                val = cols_custom_row.get(0).getMonitoringValue();
            }

            if (NumberUtils.isCreatable(val)) {
                val = String.format("%." + decimal + "f", Double.parseDouble(val));
                if (!cols_row.isEmpty()) {
                    cols_row.get(0).setMonitoringValue(val);
                } else {
                    CngScadaRealtimeMonitoringHour tmp = new CngScadaRealtimeMonitoringHour();
                    tmp.setAttributeId(data.getString("attributeId"));
                    tmp.setMonitoringValue(val);
                    Date tmpDate;
                    try {
                        tmpDate = sdf.parse(resultDate);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                    tmp.setUpdateTime(tmpDate);
                    station_day.add(tmp);
                }
                if (index >= ri_s) {
                    sheet.getRow(index).getCell(ci_s).setCellValue(Double.parseDouble(val));
                }
            } else {
                if (!cols_row.isEmpty()) {
                    cols_row.get(0).setMonitoringValue("");
                } else {
                    CngScadaRealtimeMonitoringHour tmp = new CngScadaRealtimeMonitoringHour();
                    tmp.setAttributeId(data.getString("attributeId"));
                    tmp.setMonitoringValue("");
                    Date tmpDate;
                    try {
                        tmpDate = sdf.parse(resultDate);
                    } catch (ParseException e) {
                        throw new RuntimeException(e);
                    }
                    tmp.setUpdateTime(tmpDate);
                    station_day.add(tmp);
                }
                if (index >= ri_s) {
                    sheet.getRow(index).getCell(ci_s).setCellValue("");
                }
            }

            index++;
        }
    }

    // 在表格中写入--场站设备日累计流量
    private void Write_Station_Day_Sum_Flow(JSONObject data) {
        int ri_s = data.getInteger("r_start");
        int ci_s = data.getInteger("c_start");
        int mode = data.getInteger("mode");
        List<CngScadaRealtimeMonitoringHour> cols = station_day.stream().filter((CngScadaRealtimeMonitoringHour row) -> row.getAttributeId().equals(data.getString("attributeId"))).collect(Collectors.toList());
        cols.sort(Comparator.comparing(CngScadaRealtimeMonitoringHour::getUpdateTime));

        int start = 0;
        switch (mode) {
            case 1: // 8点至次日7点
                start = 1;
                break;
            case 2: // 7点至次日6点
                start = 0;
                break;
        }

        double sum = 0;
        for (int i = start; i < start + 24; i++) {
            if (i >= cols.size()) {
                break;
            }
            String value = cols.get(i).getMonitoringValue();
            if (!NumberUtils.isCreatable(value)) {
                continue;
            }
            sum += Double.parseDouble(value);
        }

        sheet.getRow(ri_s).getCell(ci_s).setCellValue((int) sum);
    }

    // 在表格中写入--场站设备月数据
    private void Write_Station_Month(JSONObject data) {
        int ri_s = data.getInteger("r_start");
        int ri_e = data.getInteger("r_end");
        int ci_s = data.getInteger("c_start");

        List<CngScadaRealtimeMonitoringHour> cols = station_month.get(data.get("hash"));
        List<CngScadaRealtimeMonitoringHour> cols_custom = station_month_custom.get(data.get("hash"));

        String decimalPlace = data.getString("decimalPlace");
        int decimal = 2;
        if (NumberUtils.isCreatable(decimalPlace)) {
            decimal = Integer.parseInt(decimalPlace);
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String hour = data.getString("hour");

        int index = ri_s;
        for (int i = 1; i <= 31; i++) {
            String date;
            if (hour == null || hour.isEmpty()) {
                date = month + "-" + String.format("%02d", i) + " " + "07:00:00";
            } else {
                date = month + "-" + String.format("%02d", i) + " " + String.format("%02d", Integer.parseInt(data.getString("hour"))) + ":00:00";
            }

            List<CngScadaRealtimeMonitoringHour> cols_row = cols.stream().filter((CngScadaRealtimeMonitoringHour row) -> sdf.format(row.getUpdateTime()).equals(date)).collect(Collectors.toList());
            List<CngScadaRealtimeMonitoringHour> cols_custom_row = cols_custom.stream().filter((CngScadaRealtimeMonitoringHour row) -> sdf.format(row.getUpdateTime()).equals(date)).collect(Collectors.toList());

            String val = null;
            if (!cols_row.isEmpty()) {
                val = cols_row.get(0).getMonitoringValue();
            }
            if (!cols_custom_row.isEmpty()) {
                val = cols_custom_row.get(0).getMonitoringValue();
            }

            if (NumberUtils.isCreatable(val)) {
                val = String.format("%." + decimal + "f", Double.parseDouble(val));
                sheet.getRow(index).getCell(ci_s).setCellValue(Double.parseDouble(val));
            } else {
                sheet.getRow(index).getCell(ci_s).setCellValue("");
            }

            index++;
        }
    }

    // 在表格中写入--场站设备月数据公式计算
    private void Write_Station_Month_Calc(JSONObject data) {
        int ri_s = data.getInteger("r_start");
        int ri_e = data.getInteger("r_end");
        int ci_s = data.getInteger("c_start");

        List<CngScadaRealtimeMonitoringHour> cols = station_month.get(data.get("hash"));
        List<CngScadaRealtimeMonitoringHour> cols_custom = station_month_custom.get(data.get("hash"));

        String decimalPlace = data.getString("decimalPlace");
        int decimal = 2;
        if (NumberUtils.isCreatable(decimalPlace)) {
            decimal = Integer.parseInt(decimalPlace);
        }

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String hour = data.getString("hour");

        int index = ri_s;

        for (int i = 1; i <= 31; i++) {
            String today = Station_Month_Calc_GetDateByIndex(i, hour);
            String tomorrow = Station_Month_Calc_GetDateByIndex(i + 1, hour);

            List<CngScadaRealtimeMonitoringHour> cols_row_today = cols.stream().filter((CngScadaRealtimeMonitoringHour row) -> sdf.format(row.getUpdateTime()).equals(today)).collect(Collectors.toList());
            List<CngScadaRealtimeMonitoringHour> cols_custom_row_today = cols_custom.stream().filter((CngScadaRealtimeMonitoringHour row) -> sdf.format(row.getUpdateTime()).equals(today)).collect(Collectors.toList());

            List<CngScadaRealtimeMonitoringHour> cols_row_tomorrow = cols.stream().filter((CngScadaRealtimeMonitoringHour row) -> sdf.format(row.getUpdateTime()).equals(tomorrow)).collect(Collectors.toList());
            List<CngScadaRealtimeMonitoringHour> cols_custom_row_tomorrow = cols_custom.stream().filter((CngScadaRealtimeMonitoringHour row) -> sdf.format(row.getUpdateTime()).equals(tomorrow)).collect(Collectors.toList());

            String val_today = null;
            if (!cols_row_today.isEmpty()) {
                val_today = cols_row_today.get(0).getMonitoringValue();
            }
            if (!cols_custom_row_today.isEmpty()) {
                val_today = cols_custom_row_today.get(0).getMonitoringValue();
            }

            String val_tomorrow = null;
            if (!cols_row_tomorrow.isEmpty()) {
                val_tomorrow = cols_row_tomorrow.get(0).getMonitoringValue();
            }
            if (!cols_custom_row_tomorrow.isEmpty()) {
                val_tomorrow = cols_custom_row_tomorrow.get(0).getMonitoringValue();
            }

            if (NumberUtils.isCreatable(val_today) && NumberUtils.isCreatable(val_tomorrow)) {
                String result = String.format("%." + decimal + "f",
                        Double.parseDouble(String.format("%." + decimal + "f", Double.parseDouble(val_tomorrow))) -
                                Double.parseDouble(String.format("%." + decimal + "f", Double.parseDouble(val_today))));
                sheet.getRow(index).getCell(ci_s).setCellValue(Double.parseDouble(result));
            } else {
                sheet.getRow(index).getCell(ci_s).setCellValue("");
            }

            index++;
        }
    }

    // 场站设备月数据公式计算--辅助函数
    private String Station_Month_Calc_GetDateByIndex(int index, String hour) {
        Calendar calendar = Calendar.getInstance();
        SimpleDateFormat sdfMonth = new SimpleDateFormat("yyyy-MM");

        Date dateYearMonth = null;
        try {
            dateYearMonth = sdfMonth.parse(month);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        calendar.setTime(dateYearMonth);

        if (index == (calendar.getActualMaximum(Calendar.DAY_OF_MONTH) + 1)) {
            calendar.add(Calendar.MONTH, 1);
            String yearMonth = sdfMonth.format(calendar.getTime());
            if (hour == null || hour.isEmpty()) {
                return yearMonth + "-" + String.format("%02d", 1) + " " + "07:00:00";
            } else {
                return yearMonth + "-" + String.format("%02d", 1) + " " + String.format("%02d", Integer.parseInt(hour)) + ":00:00";
            }
        } else {
            String yearMonth = month;
            if (hour == null || hour.isEmpty()) {
                return yearMonth + "-" + String.format("%02d", index) + " " + "07:00:00";
            } else {
                return yearMonth + "-" + String.format("%02d", index) + " " + String.format("%02d", Integer.parseInt(hour)) + ":00:00";
            }
        }
    }

    // 在表格中写入--接入点数据
    private void Write_Into_Out(JSONObject data) {
        int ri_s = data.getInteger("r_start");
        int ci_s = data.getInteger("c_start");
        List<DispatchAccessDataDay> cols = into_out.stream().filter((DispatchAccessDataDay row) -> row.getAccessId().equals(data.getString("intoId"))).collect(Collectors.toList());

        if (!cols.isEmpty()) {
            sheet.getRow(ri_s + 2).getCell(ci_s).setCellValue(Double.parseDouble(cols.get(0).getReading()));
            sheet.getRow(ri_s + 4).getCell(ci_s).setCellValue(Double.parseDouble(cols.get(0).getPressure()));
            sheet.getRow(ri_s + 6).getCell(ci_s).setCellValue(Double.parseDouble(cols.get(0).getFlow()));
        } else {
            sheet.getRow(ri_s + 2).getCell(ci_s).setCellValue("");
            sheet.getRow(ri_s + 4).getCell(ci_s).setCellValue("");
            sheet.getRow(ri_s + 6).getCell(ci_s).setCellValue("");
        }
    }

    // 在表格中写入--交接班数据
    private void Write_Shift_Turnover(JSONObject data) {
        int ri_s = data.getInteger("r_start");
        int ci_s = data.getInteger("c_start");

        String strShift = Optional.ofNullable(data.getString("shift")).orElse("");

        if (strShift.equals("one")) {
            sheet.getRow(ri_s + 0).getCell(ci_s).setCellValue("");
            sheet.getRow(ri_s + 23).getCell(ci_s).setCellValue("值班人员：");
        } else if (strShift.equals("three")) {
            for (int i = 0; i < 3; i++) {
                sheet.getRow(ri_s + (i * 8)).getCell(ci_s).setCellValue("");
                sheet.getRow(ri_s + (i * 8 + 7)).getCell(ci_s).setCellValue("值班人员：");
            }
        }

        if (shift_turnover_station != null) {
            if (strShift.equals("one")) {
                String content = "";
                String users = "";
                for (int i = 0; i < shift_turnover_station.size(); i++) {
                    if (shift_turnover_station.get(i).getJobContent() != null) {
                        content += shift_turnover_station.get(i).getJobContent() + "\r";
                    }
                    if (i == 0) {
                        if (shift_turnover_station.get(i).getSuccessorName() != null) {
                            users = shift_turnover_station.get(i).getSuccessorName();
                        }
                    }
                }
                sheet.getRow(ri_s + 0).getCell(ci_s).setCellValue(content);
                sheet.getRow(ri_s + 23).getCell(ci_s).setCellValue("值班人员：" + users);
            } else if (strShift.equals("three")) {
                for (int i = 0; i < 3; i++) {
                    if (i < shift_turnover_station.size()) {
                        String content = shift_turnover_station.get(i).getJobContent();
                        String users = shift_turnover_station.get(i).getSuccessorName();
                        if (content != null) {
                            sheet.getRow(ri_s + (i * 8)).getCell(ci_s).setCellValue(content);
                        }
                        if (users != null) {
                            sheet.getRow(ri_s + (i * 8 + 7)).getCell(ci_s).setCellValue("值班人员：" + users);
                        }
                    }
                }
            } else if (strShift.equals("month-one")) {
                SimpleDateFormat sdFormat = new SimpleDateFormat("yyyy-MM-dd");
                Calendar calendar = Calendar.getInstance();

                for (int i = 0; i < 31; i++) {
                    try {
                        Date date = sdFormat.parse(month + "-" + String.format("%02d", i + 1));
                        calendar.setTime(date);
                        calendar.add(Calendar.DATE, 1);
                        String startTime = sdFormat.format(date) + " 08:00:00";
                        String endTime = sdFormat.format(calendar.getTime()) + " 08:00:00";

                        List<ShiftsContentVO> cols = shift_turnover_station.stream().filter((ShiftsContentVO row) -> row.getTimeRange().compareTo(startTime) >= 0 && row.getTimeRange().compareTo(endTime) <= 0).collect(Collectors.toList());

                        String content = "";
                        for (int j = 0; j < cols.size(); j++) {
                            if (cols.get(j).getJobContent() != null) {
                                content += cols.get(j).getJobContent();
                            }
                        }
                        sheet.getRow(ri_s + i).getCell(ci_s).setCellValue(content);
                    } catch (ParseException e) {
                        continue;
                    }
                }
            }
        } else if (shift_turnover_center != null) {
            if (shift_turnover_center.size() > 0) {
                String[] str = getRecordByList(shift_turnover_center.get(0).getClassNotes(), shift_turnover_center.get(0).getDutyRecord());
                int len = shift_turnover_user.get(0).size();
                String[] users = new String[len];
                for (int i = 0; i < len; i++) {
                    users[i] = shift_turnover_user.get(0).get(i).getUserName();
                }

                sheet.getRow(ri_s).getCell(ci_s).setCellValue(str[0]);
                sheet.getRow(ri_s + 7).getCell(ci_s).setCellValue("值班人员：" + StringUtil.join(users, ","));
            }
            if (shift_turnover_center.size() > 1) {
                String[] str = getRecordByList(shift_turnover_center.get(1).getClassNotes(), shift_turnover_center.get(1).getDutyRecord());
                int len = shift_turnover_user.get(1).size();
                String[] users = new String[len];
                for (int i = 0; i < len; i++) {
                    users[i] = shift_turnover_user.get(1).get(i).getUserName();
                }

                sheet.getRow(ri_s + 8).getCell(ci_s).setCellValue(str[0]);
                sheet.getRow(ri_s + 15).getCell(ci_s).setCellValue("值班人员：" + StringUtil.join(users, ","));
                sheet.getRow(ri_s + 16).getCell(ci_s).setCellValue(str[1]);
                sheet.getRow(ri_s + 23).getCell(ci_s).setCellValue("值班人员：" + StringUtil.join(users, ","));
            }
        }
    }

    // 在表格中写入--当前日期
    private void Write_Current_Date(JSONObject data) {
        int ri_s = data.getInteger("r_start");
        int ci_s = data.getInteger("c_start");

        SimpleDateFormat formatBefore = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat formatAfter = new SimpleDateFormat(data.getString("date"));
        Date dateBefore;
        try {
            dateBefore = formatBefore.parse(date);
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
        String dateAfter = formatAfter.format(dateBefore);

        sheet.getRow(ri_s).getCell(ci_s).setCellValue(dateAfter);
    }
}
